package peer.share;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.HashMap;
import java.util.Iterator;


import peer.Config;
import peer.p2pnet.PubThread;
import peer.p2pnet.PubThread_ReRegAssist;
import peer.tools.Mdb;
import peer.tools.Pmd52f;
public class CacheFileManager {
	HashMap<Mdb,CacheFile> cacheFileTable;
	public CacheFileManager(){
		cacheFileTable=new HashMap<Mdb,CacheFile> ();
		init();
	 }
	
	public BlockInfo getCancheFileInfo(Mdb mdb){
		CacheFile cf=getCacheFile(mdb);
		if(cf==null){
			return null;
		}
		return cf.getCancheFileInfo(mdb);
	}	
	
	void init(){
		File cacheDir=new File(Config.cacheDir);
		if(!cacheDir.exists()){
			cacheDir.mkdirs();
		}
		File[] fs=cacheDir.listFiles();
		for(File f:fs){
			String fn=f.getName();
			if(fn.endsWith(".pp")){
				int i=fn.indexOf(".");
				if(i>0){
					fn=fn.substring(0, i);
				}
				byte[] md=Pmd52f.hexStringToByteArray(fn);
				Mdb mdb=new Mdb(md);
				
				CacheFile cf=new CacheFile(f);
				addCacheFile(mdb,cf);
			}
			
			
		}
	}
	
	public boolean containsCacheFile(Mdb mdb){
		return cacheFileTable.containsKey(mdb);
	}
	
	CacheFile getCacheFile(Mdb mdb){
		return cacheFileTable.get(mdb);
	}
	
	void addCacheFile(Mdb mdb,CacheFile cf){
		cacheFileTable.put(mdb, cf);
	}
	
	public boolean containsPiece(Mdb mdb,int pieceNum){
		CacheFile cf=cacheFileTable.get(mdb);
		if(cf==null){
			return false;
		}
		BlockInfo bi=cf.blockInfoTable.get(mdb);
		if(bi!=null){
			int blockNum=pieceNum/64;
			return bi.containsBlock(blockNum);
		}else{
			return false;
		}
	}
	
	public boolean containsBlock(Mdb mdb,int blockNum){
		CacheFile cf=getCacheFile(mdb);
		if(cf==null){
			return false;
		}
		return cf.containsBlock(mdb, blockNum);
	}
	
	synchronized public void addBlock(Mdb mdb,int blockNum,byte[] data) throws IOException {
		if(!containsCacheFile(mdb)){
			File file=new File(Config.cacheDir+mdb+".pp");
			CacheFile cf=new CacheFile(file);
			addCacheFile(mdb,cf);
		}
		CacheFile cf=getCacheFile(mdb);
		cf.addBlock(mdb, blockNum, data);
	}
	
	public byte[] getPiece(Mdb mdb,int pieceNum) throws IOException {
		CacheFile cf=getCacheFile(mdb);
		return cf.getPiece(mdb, pieceNum);
	}
	
	public void pubAllCache(){
		System.out.println("pubAllCache");
		Iterator<Mdb> it=cacheFileTable.keySet().iterator();
		while(it.hasNext()){
			Mdb mdb=it.next();
			CacheFile cf=cacheFileTable.get(mdb);
			if(cf!=null){
				cf.pubAllCache();
			}
		}
	}
	
	public void pubAllCache_ReRegAssist(){
		System.out.println("pubAllCache_ReRegAssist");
		Iterator<Mdb> it=cacheFileTable.keySet().iterator();
		while(it.hasNext()){
			Mdb mdb=it.next();
			CacheFile cf=cacheFileTable.get(mdb);
			if(cf!=null){
				cf.pubAllCache_ReRegAssist();
			}
		}
	}
}
